<?php

	class QFlot extends QControl {

		protected $arrDataSet;
		protected $blnLines;
		protected $blnLinesFill;
		protected $blnBars;
		protected $blnPoints;
		protected $blnXTimeSeries;
		protected $blnYTimeSeries;
		protected $fltXMin;
		protected $fltXMax;
		protected $intXTickDecimals;
		protected $fltYMin;
		protected $fltYMax;
		protected $intYTickDecimals;
		protected $blnDisplayVariables;
		protected $strVariablesTitle;
	    protected $intWidth;
	    protected $intHeight;

		
		/**
		 * If this control needs to update itself from the $_POST data, the logic to do so
		 * will be performed in this method.
		 */
		public function ParsePostData() {}

		/**
		 * If this control has validation rules, the logic to do so
		 * will be performed in this method.
		 * @return boolean
		 */
		public function Validate() {return true;}
		
		public function Render($blnDisplayOutput = true) {
			// Call RenderHelper
			$this->RenderHelper(func_get_args(), __FUNCTION__);

			try {
				$this->strHtmlBefore = "<center><h1>" . $this->strName . "</center></h1>";
				$this->strHtmlBefore.= "<div id=\"" . $this->strControlId . "_flot\" style=\"width:" . $this->intWidth ."px;height:" .  $this->intHeight. "px;\"></div>";
				if($this->blnDisplayVariables){
					$this->strHtmlBefore.= "<div id=\"" . $this->strControlId . "_variables\"";
					if($this->strVariablesTitle)
						$this->strHtmlBefore.= $this->strVariablesTitle;
					$this->strHtmlBefore.= "</div>";
				}	
				$strOutput = $this->strHtmlBefore . $this->GetControlHtml();
			} catch (QCallerException $objExc) {
				$objExc->IncrementOffset();
				throw $objExc;
			}

			// Call RenderOutput, Returning its Contents
			return $this->RenderOutput($strOutput, $blnDisplayOutput);
		}

		/**
		 * Get the HTML for this Control.
		 * @return string
		 */
		public function GetControlHtml() {
			
			$strTimeSeriesFuntion = "tickFormatter: function(val) {
				  					 	var datetime = new Date( val*1000);
				  					 	return datetime.getMonth() + '/' + datetime.getDate() + '/' + datetime.getFullYear();
									 }"; 
						
			$strFloat = "\tvar datasets = {\n";
			 
			 $strXTicks = "[";
			 foreach($this->arrDataSet as $VariableName => $objInfoArray){
			 	$strFloat.="\t\t\"" . $VariableName . "\": {\n";
			    $strFloat.="\t\t\tlabel: \"" . $VariableName . "\",\n\t\t\tdata: [";
			    
			 	foreach($objInfoArray as $X => $Y) {
			 		if($this->blnXTimeSeries){
			 			$XValue = new QDateTime($X);
			 			$XValue = $XValue->Timestamp;
			 		}	
			 		else
			 			$XValue = $X;
					
			 		if($this->blnYTimeSeries){
			 			$YValue = new QDateTime($Y);
			 			$YValue = $YValue->Timestamp;
					}	
			 		else
			 			$YValue = $Y;	
			 			
			 		$strFloat.= "[" . $XValue . ", " . $YValue . "],";
			 		if($this->blnBars and !$this->blnLines ){
			 			$strFloat.= "[" . ($XValue + 1)  . ", 0],";
			 			$strXTicks.= "[($XValue + 0.5),'$VariableName (" . round($YValue,1) . "%)'],";
			 		}	
			 	}	

			 	$strFloat.= "]\n\t\t},\n";		
			 	}
				$strXTicks.= "]";

			 	//return $strFloat;
			 	
			 	$strFloat.= "\t};\n"; // end array

			 	$strFloat.= "\t// hard-code color indices to prevent them from shifting as
			    // countries are turned on/off
			    var i = 0;
			    $.each(datasets, function(key, val) {
			        val.color = i;
			        val.shadowSize= 5;
			        ++i;
			    });";			 	
			 	
			    if($this->blnDisplayVariables)
				    $strFloat.= "// insert checkboxes 
							    \tvar choiceContainer = $(\"#" . $this->strControlId . "_variables\");\n
			    				\t$.each(datasets, function(key, val) {\n
			        			\t\tchoiceContainer.append('<br/><input type=\"checkbox\" name=\"' + key + '\" checked=\"checked\" >' + val.label + '</input>');\n
			    				\t});\n
			    
			    				\tchoiceContainer.find(\"input\").click(plotAccordingToChoices);\n";
			
			    
			    $strFloat.= "\tfunction plotAccordingToChoices() {\n
			        \t\tvar data = []; \n";
			
			    if($this->blnDisplayVariables)
			    	$strFloat.="\t\tchoiceContainer.find(\"input:checked\").each(function () {\n
			            \t\tvar key = $(this).attr(\"name\");\n
			            \t\tif (key && datasets[key])\n
			                \t\t\tdata.push(datasets[key]);
			        });\n";
			    else
			    	$strFloat.=" for(id in datasets)
			    					data.push(datasets[id]);";	

					$strFloat.= "if (data.length > 0)
			        	    $.plot($(\"#" . $this->strControlId ."_flot\"), data, {\n";

			if(isset($this->fltYMin))
				$strFloat.=	"yaxis: { min: " . $this->fltYMin ." },\n";	

			if(isset($this->fltYMax))
				$strFloat.=	"yaxis: { max: " . $this->fltYMax ." },\n";	
				
			if(isset($this->intYTickDecimals))
		 		$strFloat.= "yaxis: { tickDecimals: " . $this->intYTickDecimals ."},\n";	                

		 	if(isset($this->blnYTimeSeries))
		 		$strFloat.= "yaxis: {" . $strTimeSeriesFuntion . "},\n";		 		
		 		
			if(isset($this->fltXMin))
				$strFloat.=	"xaxis: { min: " . $this->fltXMin ." },\n";			

			if(isset($this->fltXMax))
				$strFloat.=	"xaxis: { max: " . $this->fltXMax ." },\n";	
				
		 	if(isset($this->intXTickDecimals))
		 		$strFloat.= "xaxis: { tickDecimals: " . $this->intXTickDecimals ."},\n"; 	
			 			 		
		 	if(isset($this->blnXTimeSeries))
		 		$strFloat.= "xaxis: {" . $strTimeSeriesFuntion . "},\n";

			if($this->blnBars and strlen($strXTicks)> 2)
		 		$strFloat.="xaxis: { ticks: $strXTicks },\n";
	
		 	if($this->blnBars){
		 		$strFloat.= "bars: { show: true } ,\n";
		 		$strFloat.= "legend: { show: false } ,\n";
		 	}
		 		
		 	if(isset($this->blnLines)){
		 		$strFloat.= "lines: { show: true,\n";
		 		if(isset($this->blnLinesFill))
		 			$strFloat.= "fill: true";
		 		$strFloat.= "},\n";
		 	}
		 	
		 	if($this->blnPoints)
		 		$strFloat.= "points: { show: true },\n";
			 		
			 	$strFloat.= "});\n
			    }
			
			    plotAccordingToChoices();\n";
			 	
			 	//print_r("<pre>" . $strFloat . "</pre>");
				QApplication::ExecuteJavaScript($strFloat);
		}

		/**
		 * Constructor for this control
		 * @param mixed $objParentObject Parent QForm or QControl that is responsible for rendering this control
		 * @param string $strControlId optional control ID
		 */
		public function __construct($objParentObject, $strControlId = null) {
			try {
				parent::__construct($objParentObject, $strControlId);
			} catch (QCallerException $objExc) { $objExc->IncrementOffset(); throw $objExc; }
			
			$this->arrDataSet = array();
			$this->intWidth = 500;
			$this->intHeight  = 300;
		}

		// For any JavaScript calls that need to be made whenever this control is rendered or re-rendered
//		public function GetEndScript() {
//			$strToReturn = parent::GetEndScript();
//			return $strToReturn;
//		}

		// For any HTML code that needs to be rendered at the END of the QForm when this control is INITIALLY rendered.
//		public function GetEndHtml() {
//			$strToReturn = parent::GetEndHtml();
//			return $strToReturn;
//		}

		/////////////////////////
		// Public Properties: GET
		/////////////////////////
		public function __get($strName) {
			switch ($strName) {
				case "DataSet": return $this->arrDataSet;
				default:
					try {
						return parent::__get($strName);
					} catch (QCallerException $objExc) { $objExc->IncrementOffset(); throw $objExc; }
			}
		}

		/////////////////////////
		// Public Properties: SET
		/////////////////////////
		public function __set($strName, $mixValue) {
			$this->blnModified = true;

			switch ($strName) {

				case "DataSet":
					try {
						$this->arrDataSet = QType::Cast($mixValue, QType::ArrayType);
						break;
					} catch (QInvalidCastException $objExc) {
						$objExc->IncrementOffset();
						throw $objExc;
					}
				case "XTimeSeries":
					try {
						$this->blnXTimeSeries = QType::Cast($mixValue, QType::Boolean);
						break;
					} catch (QInvalidCastException $objExc) {
						$objExc->IncrementOffset();
						throw $objExc;
					}
				case "YTimeSeries":
					try {
						$this->blnYTimeSeries = QType::Cast($mixValue, QType::Boolean);
						break;
					} catch (QInvalidCastException $objExc) {
						$objExc->IncrementOffset();
						throw $objExc;
					}
				case "Lines":
					try {
						$this->blnLines = QType::Cast($mixValue, QType::Boolean);
						break;
					} catch (QInvalidCastException $objExc) {
						$objExc->IncrementOffset();
						throw $objExc;
					}
				case "LinesFill":
					try {
						$this->blnLinesFill = QType::Cast($mixValue, QType::Boolean);
						break;
					} catch (QInvalidCastException $objExc) {
						$objExc->IncrementOffset();
						throw $objExc;
					}
				case "Bars":
					try {
						$this->blnBars= QType::Cast($mixValue, QType::Boolean);
						break;
					} catch (QInvalidCastException $objExc) {
						$objExc->IncrementOffset();
						throw $objExc;
					}
				case "Points":
					try {
						$this->blnPoints= QType::Cast($mixValue, QType::Boolean);
						break;
					} catch (QInvalidCastException $objExc) {
						$objExc->IncrementOffset();
						throw $objExc;
					}	
				case "XMin":
					try {
						$this->fltXMin = QType::Cast($mixValue, QType::Float);
						break;
					} catch (QInvalidCastException $objExc) {
						$objExc->IncrementOffset();
						throw $objExc;
					}
				case "XMax":
					try {
						$this->fltXMax = QType::Cast($mixValue, QType::Float);
						break;
					} catch (QInvalidCastException $objExc) {
						$objExc->IncrementOffset();
						throw $objExc;
					}
				case "YMin":
					try {
						$this->fltYMin = QType::Cast($mixValue, QType::Float);
						break;
					} catch (QInvalidCastException $objExc) {
						$objExc->IncrementOffset();
						throw $objExc;
					}
				case "YMax":
					try {
						$this->fltYMax = QType::Cast($mixValue, QType::Float);
						break;
					} catch (QInvalidCastException $objExc) {
						$objExc->IncrementOffset();
						throw $objExc;
					}
				case "YTickDecimals":
					try {
						$this->intYTickDecimals = QType::Cast($mixValue, QType::Integer);
						break;
					} catch (QInvalidCastException $objExc) {
						$objExc->IncrementOffset();
						throw $objExc;
					}
				case "XTickDecimals":
					try {
						$this->intXTickDecimals = QType::Cast($mixValue, QType::Integer);
						break;
					} catch (QInvalidCastException $objExc) {
						$objExc->IncrementOffset();
						throw $objExc;
					}	
				case "DisplayVariables":
					try {
						$this->blnDisplayVariables = QType::Cast($mixValue, QType::Boolean);
						break;
					} catch (QInvalidCastException $objExc) {
						$objExc->IncrementOffset();
						throw $objExc;
					}	
				case "VariablesTitle":
					try {
						$this->strVariablesTitle = QType::Cast($mixValue, QType::String);
						break;
					} catch (QInvalidCastException $objExc) {
						$objExc->IncrementOffset();
						throw $objExc;
					}
				case "Width":
					try {
						$this->intWidth = QType::Cast($mixValue, QType::Integer);
						break;
					} catch (QInvalidCastException $objExc) {
						$objExc->IncrementOffset();
						throw $objExc;
					}
				case "Height":
					try {
						$this->intHeight = QType::Cast($mixValue, QType::Integer);
						break;
					} catch (QInvalidCastException $objExc) {
						$objExc->IncrementOffset();
						throw $objExc;
					}									
				default:
					try {
						return (parent::__set($strName, $mixValue));
					} catch (QCallerException $objExc) { $objExc->IncrementOffset(); throw $objExc; }
			}
		}
	}
?>